""" bricks.py
Data structures for parsing and reading
"""

class Variable:
    def __init__(self, id, context):
        self.id = id
        self.context = context

    def resolve(self):
        return self.context[str(self.id)]

class Brick:
    def __init__(self, type, id, name):
        self.type = type
        self.id = id
        self.name = name

    def reader_format(self):
        return None

    def traverse(self, visitor):
        visitor.prefix_traverse(self)
        visitor.suffix_traverse(self)

class Child(Brick):
    def __init__(self, id, name):
        Brick.__init__(self,"child", id, name)
        self.bricks = []
    
    def addBrick(self, brick):
        self.bricks.append(brick)
    
    def traverse(self, visitor):
        visitor.prefix_traverse(self)
        for b in self.bricks:
            b.traverse(visitor)
        visitor.suffix_traverse(self)


class Sequence(Brick):
    def __init__(self, id, name):
        Brick.__init__(self,"sequence", id, name)
        self.bricks = []
    
    def addBrick(self, brick):
        self.bricks.append(brick)
    
    def traverse(self, visitor):
        visitor.prefix_traverse(self)
        for b in self.bricks:
            b.traverse(visitor)
        visitor.suffix_traverse(self)

class Integer(Brick):
    def __init__(self, id, name,precision=32):
        Brick.__init__(self,"int", id, name)
        self.precision = precision

    def reader_format(self):
        if self.precision == 32:
            return ">i"
        elif self.precision == 16:
            return ">h"
        elif self.precision == 64:
            return ">q"

class Float(Brick):
    def __init__(self, id, name, precision=32):
        Brick.__init__(self,"float", id, name)
        self.precision = precision

    def reader_format(self):
        if self.precision == 32:
            return ">f"
        elif self.precision == 64:
            return ">d"

class String(Brick):
    def __init__(self, id, name, padded = True, length =-1):
        Brick.__init__(self,"string",id,name)
        self.padded = padded
        self.length = length

    def reader_format(self):
        if self.padded:
            return ">" + self.length + "s"
        else:
            return ""

class Byte(Brick):
    def __init__(self, id, name):
        Brick.__init__(self,"byte", id, name)

    def reader_format(self):
        return ">b"

class Array(Brick):
    def __init__(self,id,name, count_variable):
        Brick.__init__(self,"array", id, name)
        self.count = count_variable
        self.brick_sequence = Sequence("array_"+name,"array_"+id)
    
    def addBrick(self, b):
        self.brick_sequence.addBrick(b)

    def traverse(self, visitor):
        visitor.prefix_traverse(self)
        for i in xrange(self.count.resolve()):
            self.brick_sequence.traverse(visitor)
        visitor.suffix_traverse(self)

class Switch(Brick):
    def __init__(self,id,name, variable):
        Brick.__init__(self,"switch", id, name)
        self.variable = variable
        self.bricks = dict()
    
    def addBrick(self, switch_case, b):
        self.bricks[str(switch_case)] = b

    def traverse(self, visitor):
        visitor.prefix_traverse(self)
        self.bricks[str(self.variable.resolve())].traverse(visitor)
        visitor.suffix_traverse(self)

